﻿using System;
using System.Collections.Generic;
using System.Text;
using Quartz;
using ShootSearch.Util.Serializers;
using System.Xml.Serialization;
using ShootSearch.Util;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;

namespace ShootSearch.Core
{
    [Serializable]
    [TypeConverter(typeof(ExpandableConverter<TaskConfig>))]
    public class TaskConfig
    {
        public string TaskName { get; set; }
        [XmlArray]
        [XmlArrayItem("Job")]
        public List<JobConfig> Jobs { get; set; }
        public JobStatus Status { get; set; }
        public int CurrentJob { get; set; }
        [XmlIgnore]
        public string ContextPath { get; set; }

        public TaskConfig()
        {
            Jobs = new List<JobConfig>();
        }

        public void Save(string path)
        {
            XmlFormatter.ToXmlFile(this, path);
        }

        public JobDetail GetCurrentJob()
        {
            if (CurrentJob < Jobs.Count)
            {
                JobDetail root = GetJobDetail(Jobs[CurrentJob]);
                JobDetail current = root;
                for (int i = CurrentJob + 1; i < Jobs.Count; i++)
                {
                    JobDetail next = GetJobDetail(Jobs[i]);
                    current.JobDataMap.Add(Task.JOB_NEXT, next);
                    current = next;
                }
                return root;
            }
            return null;
        }


        public JobDetail GetJobDetail(JobConfig jobConfig)
        {
            if (jobConfig != null && jobConfig.Type != null)
            {
                ISpiderMan job = jobConfig.GetObjectWithConfig() as ISpiderMan;
                JobDetail detail = new JobDetail(jobConfig.Name, null, job.GetType());
                detail.JobDataMap.Add(Task.JOB_CONFIG, job.Config);
                detail.JobDataMap.Add(Task.JOB_CONTEXT_PATH, this.ContextPath);

                return detail;
            }
            return null;
        }

        public static TaskConfig Load(string path)
        {
            TaskConfig config = new TaskConfig();
            config = XmlFormatter.FromFile(path, config.GetType()) as TaskConfig;
            config.ContextPath = new FileInfo(path).Directory.FullName;
            return config;
        }       
        
    }

    public class JobConfig : AssemblyWithConfig, IXmlSerializable
    {
        public string Name { get; set; }
        
        public JobConfig()
            :base()
        { }

        public JobConfig(ISpiderMan job)
            :base(job)
        { }

        public JobConfig(Type jobType)
            : base(jobType)
        {}



        #region IXmlSerializable Members

        System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
        {
            return base.GetSchema();
        }

        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            reader.ReadToFollowing("Name");
            Name = reader.ReadString();

            base.ReadXml(reader);
        }

        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement("Name");
            writer.WriteString(Name);
            writer.WriteEndElement();
            base.WriteXml(writer);
        }

        #endregion
    }
   
}
